package core

import (
	"errors"
	"log"
	"mime"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
	ginSwagger "github.com/swaggo/gin-swagger"
	"github.com/swaggo/gin-swagger/swaggerFiles"

	_ "away.wei/minidevpos/docs"
	"away.wei/minidevpos/global"
)

type IGinRouter interface {
	AddPublicRouter(router *gin.Engine)
	AddPrivateRouter(router *gin.Engine)
}

type GinServer struct {
	router *gin.Engine
}

type GinRouterHandler func(*gin.Engine)

func (ginserver *GinServer) Handler(anyThingHandler GinRouterHandler) {
	anyThingHandler(ginserver.router)
}

func (ginserver *GinServer) NewServer() *gin.Engine {
	gin.SetMode(gin.ReleaseMode)
	ginserver.router = gin.New()

	ginRouter.AddPublicRouter(&ginserver.router.RouterGroup)

	accounts := make(gin.Accounts)
	for k, v := range global.Settings.Accounts {
		accounts[k] = v
	}
	authorized := ginserver.router.Group("/", gin.BasicAuth(accounts))
	ginRouter.AddPrivateRouter(authorized)
	return ginserver.router
}

func (ginserver *GinServer) Listen(addr string) error {
	if ginserver.router == nil {
		return errors.New("请先初始化 NewServer()")
	}

	// server := &http.Server{
	// 	Addr:           addr,
	// 	Handler:        ginserver.router,
	// 	MaxHeaderBytes: 1 << 20,
	// }

	// err := server.ListenAndServe()
	log.Printf("服务启动：http://%s", addr)
	err := ginserver.router.Run(addr)
	if err != nil {
		log.Println(err.Error())
		os.Exit(0)
	}

	return err
}

func (ginserver *GinServer) AddRouter(ginRouter IGinRouter) {
	ginRouter.AddPublicRouter(ginserver.router)
	ginRouter.AddPrivateRouter(ginserver.router)
}

func (ginserver *GinServer) AddSwagger() {
	ginserver.router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}

func (ginserver *GinServer) AddStatic(relativePath, root string) {
	ginserver.router.Static(relativePath, root)
}
func (ginserver *GinServer) AddWeb() {
	mime.AddExtensionType(".js", "application/javascript; charset=utf-8")
	root := global.Abpath + "/wwwroot"
	ginserver.router.Static("/assets", root+"/assets")
	ginserver.router.StaticFile("/favicon.ico", root+"/favicon.ico")
	ginserver.router.StaticFile("/favicon.svg", root+"/favicon.svg")
	ginserver.router.StaticFile("/", root+"/index.html")
}

func (ginserver *GinServer) AddCore() {
	ginserver.router.Use(func(c *gin.Context) {
		method := c.Request.Method
		origin := c.Request.Header.Get("Origin")
		c.Header("Access-Control-Allow-Origin", origin)
		c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
		c.Header("Access-Control-Allow-Credentials", "true")

		// 放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}
		// 处理请求
		c.Next()
	})
}
